home *** CD-ROM | disk | FTP | other *** search
/ T&A 2 the Maxx 3 / T and A 2 The Maxx Number 3.iso / viewers / unixview / xgiftar.z / xgiftar / buildshar.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  3KB  |  125 lines

  1. /* buildshar.c:
  2.  *
  3.  * utility program to figure out how to pack shar files.  it doesn't try
  4.  * very hard.
  5.  *
  6.  * this program is in the public domain.
  7.  *
  8.  * jim frost 09.25.90
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14.  
  15. /* this defines the size of the shar file not including anything that got
  16.  * added by shar.  should be considerably smaller than 64000.
  17.  */
  18.  
  19. #define SHAR_SIZE 40000
  20.  
  21. struct file {
  22.   char *name;
  23.   int size;
  24.   struct file *next;
  25. };
  26.  
  27. struct shar {
  28.   struct file *file;
  29.   struct shar *next;
  30. };
  31.  
  32. main(argc, argv)
  33.      int    argc;
  34.      char **argv;
  35. { int num_files, files_left;
  36.   struct file *files;
  37.   struct stat sbuf;
  38.   struct shar *shar_list;
  39.   struct shar *cur_shar;
  40.   struct file *cur_file;
  41.   int shar_size, shar_num, num_shars;
  42.   int a;
  43.  
  44.   if (argc < 2) {
  45.     fprintf(stderr, "Usage: %s [files]\n", *argv);
  46.   }
  47.  
  48.   /* build table of filenames
  49.    */
  50.  
  51.   files= (struct file *)malloc(sizeof(struct file) * (argc - 1));
  52.   for (a= 0, num_files= 0; *(++argv); a++) {
  53.     if (stat(*argv, &sbuf) < 0) {
  54.       perror(*argv);
  55.       files[a].name= NULL;
  56.       continue;
  57.     }
  58.     num_files++;
  59.     files[a].name= *argv;
  60.     files[a].size= sbuf.st_size;
  61.   }
  62.  
  63.   /* try to fit files.  this is not a bright algorithm.
  64.    */
  65.  
  66.   shar_list= cur_shar= (struct shar *)malloc(sizeof(struct shar));
  67.   cur_shar->file= NULL;
  68.   cur_file= NULL;
  69.   shar_size= 0;
  70.  
  71.   for (files_left= num_files; files_left;) {
  72.  
  73.     /* look for a file that'll fit in the current shar
  74.      */
  75.  
  76.     for (a= 0; a < num_files; a++)
  77.       if (files[a].name &&
  78.       ((shar_size + files[a].size <= SHAR_SIZE) ||
  79.        ((shar_size == 0) && (files[a].size > SHAR_SIZE)))) {
  80.     shar_size += files[a].size;
  81.     if (cur_file) {
  82.       cur_file->next= (struct file *)malloc(sizeof(struct file));
  83.       cur_file= cur_file->next;
  84.     }
  85.     else
  86.       cur_shar->file= cur_file= (struct file *)malloc(sizeof(struct file));
  87.     cur_file->name= files[a].name;
  88.     cur_file->next= NULL;
  89.     files[a].name= NULL;
  90.     files_left--;
  91.     break;
  92.       }
  93.  
  94.     /* if nothing fit, make a new shar file
  95.      */
  96.  
  97.     if (a == num_files) {
  98.       cur_shar->next= (struct shar *)malloc(sizeof(struct shar));
  99.       cur_shar= cur_shar->next;
  100.       cur_shar->file= NULL;
  101.       cur_shar->next= NULL;
  102.       cur_file= NULL;
  103.       shar_size= 0;
  104.     }
  105.   }
  106.  
  107.   /* find out how many shar files we need for -e flag
  108.    */
  109.  
  110.   for (num_shars= 0, cur_shar= shar_list; cur_shar; num_shars++)
  111.     cur_shar= cur_shar->next;
  112.  
  113.   /* output each shar command line
  114.    */
  115.  
  116.   for (shar_num= 1, cur_shar= shar_list; cur_shar; shar_num++) {
  117.     printf("shar -n %d -e %d", shar_num, num_shars);
  118.     for (cur_file= cur_shar->file; cur_file; cur_file= cur_file->next)
  119.       printf(" %s", cur_file->name);
  120.     cur_shar= cur_shar->next;
  121.     printf(" > shar.%d\n", shar_num);
  122.   }
  123.   exit(0);
  124. }
  125.